using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using WpfApp_ChenxiConsole.TCP;
using System.Text.Json;
using System.Collections.Generic;

namespace WpfApp_ChenxiConsole.OTA
{
    /// <summary>
    /// 固件升级状态枚举
    /// </summary>
    public enum FirmwareUpgradeState
    {
        Ready,                  // 就绪状态
        NotifyingEcu,           // 通知ECU设备升级
        ErasingFlash,           // 控制ECU设备擦除flash
        SendingData,            // 下发数据流
        VerifyingData,          // 校验数据
        Resetting,              // 复位
        Completed,              // 升级完成
        Failed                  // 升级失败
    }

    /// <summary>
    /// BottomUnitOtaWindow.xaml 的交互逻辑
    /// </summary>
    public partial class BottomUnitOtaWindow : Window
    {
        // 定时器，用于定期检查接收队列中的消息
        private DispatcherTimer? _messageCheckTimer;
        
        // 选定的TCP客户端控件
        private TcpConsoleControl? _selectedTcpConsole;
        
        // 自定义消息处理器ID
        private string _messageHandlerId = "";

        // 固件升级状态机相关
        private FirmwareUpgradeState _currentUpgradeState = FirmwareUpgradeState.Ready;
        private DispatcherTimer? _upgradeStateMachineTimer;
        private EcuOtaManager _ecuOtaManager = new EcuOtaManager();
        private List<string> _receivedResponses = new List<string>();
        
        /// <summary>
        /// 构造函数，支持传入选定的TCP客户端控件
        /// </summary>
        /// <param name="tcpConsoleControl">选定的TCP客户端控件</param>
        public BottomUnitOtaWindow(TcpConsoleControl? tcpConsoleControl = null)
        {
            InitializeComponent();
            InitializeWindow();
            
            // 保存选定的TCP客户端控件
            _selectedTcpConsole = tcpConsoleControl;
            
            // 生成唯一的消息处理器ID
            _messageHandlerId = $"EcuOtaHandler_{Guid.NewGuid().ToString().Substring(0, 8)}";
            
            // 如果有选定的TCP客户端，更新状态栏显示
            if (_selectedTcpConsole != null)
            {
                StatusTextBlock.Text = "已绑定到TCP客户端";
                StatusTextBlock.Foreground = FindResource("InfoBrush") as System.Windows.Media.Brush;
            }
            
            // 初始化定时器，每100毫秒检查一次队列
            _messageCheckTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(100)
            };
            _messageCheckTimer.Tick += MessageCheckTimer_Tick;
            _messageCheckTimer.Start();

            // 初始化升级状态机定时器
            _upgradeStateMachineTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromSeconds(1) // 每秒检查一次状态
            };
            _upgradeStateMachineTimer.Tick += UpgradeStateMachineTimer_Tick;
            _upgradeStateMachineTimer.IsEnabled = false;
            
            // 注册消息过滤器处理器，将cmd为996的JSON消息添加到ECU升级窗口的接收队列
            MessageFilter.RegisterHandler(_messageHandlerId, message =>
            {
                try
                {
                    EcuOtaManager.AddToReceivedQueue(message);
                    _receivedResponses.Add(message);
                }
                catch (Exception ex)
                {
                    // 这里可以添加错误日志记录
                    Console.WriteLine($"添加消息到ECU升级窗口接收队列失败: {ex.Message}");
                }
            });
        }

        /// <summary>
        /// 初始化窗口
        /// </summary>
        private void InitializeWindow()
        {
            // 默认选择第一个设备类型
            if (DeviceTypeComboBox.Items.Count > 0)
            {
                DeviceTypeComboBox.SelectedIndex = 0;
            }

            // 初始化统计结果文本
            DeviceIdStatisticsTextBlock.Text = "请点击\"统计设备ID\"按钮进行设备ID统计";
        }

        /// <summary>
        /// 固件升级按钮点击事件
        /// </summary>
        private void FirmwareUpgradeButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 检查是否已绑定TCP客户端
                if (_selectedTcpConsole == null)
                {
                    StatusTextBlock.Text = "请先绑定TCP客户端";
                    StatusTextBlock.Foreground = FindResource("DangerBrush") as System.Windows.Media.Brush;
                    return;
                }

                // 检查是否正在升级过程中
                if (_currentUpgradeState != FirmwareUpgradeState.Ready && 
                    _currentUpgradeState != FirmwareUpgradeState.Completed && 
                    _currentUpgradeState != FirmwareUpgradeState.Failed)
                {
                    StatusTextBlock.Text = "正在进行固件升级，请等待...";
                    StatusTextBlock.Foreground = FindResource("InfoBrush") as System.Windows.Media.Brush;
                    return;
                }

                // 准备开始固件升级
                StatusTextBlock.Text = "开始固件升级...";
                StatusTextBlock.Foreground = FindResource("InfoBrush") as System.Windows.Media.Brush;
                FirmwareUpgradeButton.IsEnabled = false;
                CountDeviceIdButton.IsEnabled = false;
                _receivedResponses.Clear();

                // 启动状态机
                _currentUpgradeState = FirmwareUpgradeState.NotifyingEcu;
                _upgradeStateMachineTimer!.IsEnabled = true;

                // 发送通知ECU设备升级的命令
                SendOtaCommand(1); // 1表示通知升级
                StatusTextBlock.Text = "正在通知ECU设备升级...";
            }
            catch (Exception ex)
            {
                StatusTextBlock.Text = "启动固件升级失败";
                StatusTextBlock.Foreground = FindResource("DangerBrush") as System.Windows.Media.Brush;
                Console.WriteLine($"启动固件升级失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 升级状态机定时器处理方法
        /// </summary>
        private void UpgradeStateMachineTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                switch (_currentUpgradeState)
                {
                    case FirmwareUpgradeState.NotifyingEcu:
                        // 检查是否收到ECU的响应
                        if (HasReceivedResponse(1)) // 假设1是通知升级的响应标记
                        {
                            // 进入下一个状态：擦除Flash
                            _currentUpgradeState = FirmwareUpgradeState.ErasingFlash;
                            SendOtaCommand(2); // 2表示擦除Flash
                            StatusTextBlock.Text = "正在擦除ECU设备Flash...";
                        }
                        break;

                    case FirmwareUpgradeState.ErasingFlash:
                        // 检查是否收到ECU的响应
                        if (HasReceivedResponse(2)) // 假设2是擦除Flash的响应标记
                        {
                            // 进入下一个状态：下发数据流
                            _currentUpgradeState = FirmwareUpgradeState.SendingData;
                            SendOtaCommand(3); // 3表示下发数据流
                            StatusTextBlock.Text = "正在下发固件数据流...";
                        }
                        break;

                    case FirmwareUpgradeState.SendingData:
                        // 检查是否收到ECU的响应
                        if (HasReceivedResponse(3)) // 假设3是数据流传输完成的响应标记
                        {
                            // 进入下一个状态：校验数据
                            _currentUpgradeState = FirmwareUpgradeState.VerifyingData;
                            SendOtaCommand(4); // 4表示校验数据
                            StatusTextBlock.Text = "正在校验固件数据...";
                        }
                        break;

                    case FirmwareUpgradeState.VerifyingData:
                        // 检查是否收到ECU的响应
                        if (HasReceivedResponse(4)) // 假设4是数据校验完成的响应标记
                        {
                            // 进入下一个状态：复位
                            _currentUpgradeState = FirmwareUpgradeState.Resetting;
                            SendOtaCommand(5); // 5表示复位
                            StatusTextBlock.Text = "正在复位ECU设备...";
                        }
                        break;

                    case FirmwareUpgradeState.Resetting:
                        // 检查是否收到ECU的响应
                        if (HasReceivedResponse(5)) // 假设5是复位完成的响应标记
                        {
                            // 升级完成
                            _currentUpgradeState = FirmwareUpgradeState.Completed;
                            _upgradeStateMachineTimer!.IsEnabled = false;
                            StatusTextBlock.Text = "固件升级完成";
                            StatusTextBlock.Foreground = FindResource("SuccessBrush") as System.Windows.Media.Brush;
                            FirmwareUpgradeButton.IsEnabled = true;
                            CountDeviceIdButton.IsEnabled = true;
                        }
                        break;

                    // 其他状态不需要处理
                }
            }
            catch (Exception ex)
            {
                // 处理状态机运行过程中的错误
                _currentUpgradeState = FirmwareUpgradeState.Failed;
                _upgradeStateMachineTimer!.IsEnabled = false;
                StatusTextBlock.Text = "固件升级失败";
                StatusTextBlock.Foreground = FindResource("DangerBrush") as System.Windows.Media.Brush;
                FirmwareUpgradeButton.IsEnabled = true;
                CountDeviceIdButton.IsEnabled = true;
                Console.WriteLine($"固件升级状态机错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 发送OTA命令到ECU设备
        /// </summary>
        /// <param name="commandType">命令类型</param>
        private async void SendOtaCommand(int commandType)
        {
            try
            {
                if (_selectedTcpConsole == null || !_selectedTcpConsole.IsConnected || _selectedTcpConsole.TcpClientManager == null)
                {
                    throw new Exception("未绑定TCP客户端或连接已断开");
                }

                // 创建命令JSON对象
                var commandObject = new
                {
                    cmd = 996, // OTA命令标识
                    type = commandType, // 命令类型
                    timestamp = DateTime.Now.Ticks
                };

                // 序列化JSON对象
                string jsonCommand = JsonSerializer.Serialize(commandObject);

                // 发送命令到TCP客户端
                bool isSent = await _selectedTcpConsole.TcpClientManager.SendMessageAsync(jsonCommand, Encoding.UTF8);
                if (isSent)
                {
                    Console.WriteLine($"已发送OTA命令: {jsonCommand}");
                }
                else
                {
                    throw new Exception("发送命令失败");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送OTA命令失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 检查是否已收到指定类型的响应
        /// </summary>
        /// <param name="responseType">响应类型</param>
        /// <returns>是否已收到响应</returns>
        private bool HasReceivedResponse(int responseType)
        {
            // 简单实现：检查接收到的响应中是否包含指定类型的响应
            // 实际应用中应该根据具体的协议格式进行解析
            foreach (var response in _receivedResponses)
            {
                if (response.Contains($"\"type\":{responseType}") && response.Contains($"\"result\":\"success\""))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 统计设备ID按钮点击事件
        /// </summary>
        private void CountDeviceIdButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 检查是否正在升级过程中
                if (_currentUpgradeState != FirmwareUpgradeState.Ready && 
                    _currentUpgradeState != FirmwareUpgradeState.Completed && 
                    _currentUpgradeState != FirmwareUpgradeState.Failed)
                {
                    StatusTextBlock.Text = "正在进行固件升级，请等待...";
                    StatusTextBlock.Foreground = FindResource("InfoBrush") as System.Windows.Media.Brush;
                    return;
                }

                // 获取选中的设备类型
                var selectedDeviceType = DeviceTypeComboBox.SelectedItem as ComboBoxItem;
                if (selectedDeviceType == null)
                {
                    StatusTextBlock.Text = "请先选择设备类型";
                    StatusTextBlock.Foreground = FindResource("DangerBrush") as System.Windows.Media.Brush;
                    return;
                }

                string deviceType = selectedDeviceType.Content?.ToString() ?? "未知设备";
                StatusTextBlock.Text = $"正在统计{deviceType}的设备ID...";
                StatusTextBlock.Foreground = FindResource("InfoBrush") as System.Windows.Media.Brush;

                // 这里是占位实现，具体实现方法后续给出
                // 模拟设备ID统计过程
                SimulateDeviceIdStatistics(deviceType);
            }
            catch (Exception ex)
            {
                StatusTextBlock.Text = $"统计设备ID失败：{ex.Message}";
                StatusTextBlock.Foreground = FindResource("DangerBrush") as System.Windows.Media.Brush;
            }
        }

        /// <summary>
        /// 模拟设备ID统计过程
        /// </summary>
        /// <param name="deviceType">设备类型</param>
        private void SimulateDeviceIdStatistics(string deviceType)
        {
            // 这里是模拟实现，实际应用中需要替换为真实的设备ID统计逻辑
            // 生成一些随机的设备ID示例
            Random random = new Random();
            int deviceCount = random.Next(5, 20);
            StringBuilder deviceIdsBuilder = new StringBuilder();

            deviceIdsBuilder.AppendLine($"设备类型: {deviceType}");
            deviceIdsBuilder.AppendLine($"设备总数: {deviceCount}");
            deviceIdsBuilder.AppendLine("设备ID列表:");

            for (int i = 1; i <= deviceCount; i++)
            {
                // 生成随机的设备ID
                string deviceId = $"DEV-{deviceType[0]}-{DateTime.Now.Year}{random.Next(1000, 9999)}";
                deviceIdsBuilder.AppendLine($"{i}. {deviceId}");
            }

            // 更新UI
            DeviceIdStatisticsTextBlock.Text = deviceIdsBuilder.ToString();
            StatusTextBlock.Text = $"设备ID统计完成";
            StatusTextBlock.Foreground = FindResource("SuccessBrush") as System.Windows.Media.Brush;
        }

        /// <summary>
        /// 定时器Tick事件，检查接收队列中的消息
        /// </summary>
        private void MessageCheckTimer_Tick(object? sender, EventArgs e)
        {
            // 处理队列中的所有消息
            while (EcuOtaManager.ReceivedMessagesQueue.TryDequeue(out string? message))
            {
                try
                {
                    // 处理接收到的消息
                    ProcessReceivedMessage(message);
                }
                catch (Exception ex)
                {
                    StatusTextBlock.Text = $"处理接收到的消息失败：{ex.Message}";
                    StatusTextBlock.Foreground = FindResource("DangerBrush") as System.Windows.Media.Brush;
                }
            }
        }
        
        /// <summary>
        /// 处理接收到的消息
        /// </summary>
        /// <param name="message">接收到的消息</param>
        private void ProcessReceivedMessage(string? message)
        {
            // 这里可以根据实际需求处理消息
            // 例如：显示消息内容、解析消息、触发相应的操作等
            
            // 示例：在状态栏显示接收到新消息
            StatusTextBlock.Text = "接收到ECU升级相关消息";
            StatusTextBlock.Foreground = FindResource("InfoBrush") as System.Windows.Media.Brush;
            
            // 示例：在设备ID统计文本框中显示消息
            string safeMessage = message ?? "(空消息)";
            DeviceIdStatisticsTextBlock.Text += $"\n\n接收到的消息：{safeMessage}";
        }
        
        /// <summary>
        /// 关闭按钮点击事件
        /// </summary>
        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            // 停止定时器
            if (_messageCheckTimer != null)
            {
                _messageCheckTimer.Stop();
                _messageCheckTimer = null;
            }
            
            // 注销消息过滤器处理器
            MessageFilter.UnregisterHandler(_messageHandlerId);
            
            this.Close();
        }
    }
}